//
//  Man.m
//  MyBlocks
//
//  Created by apple on 2020/6/6.
//  Copyright © 2020 apple. All rights reserved.
//

#import "Man.h"
//#import "Car.h"
//#import "Car+NewCar.h"
#import <objc/runtime.h>


@implementation Man

+(void)load{
    
    NSLog(@"Man --- load");
    
}
+(void)initialize{
    NSLog(@"Man --- initialize");
}
//子类初始化时，会先调用父类的 -init() 方法，然后调用自身的 -init() 方法，并且每次初始化时都会调用
-(instancetype)init{
    if (self = [super init]) {
        NSLog(@"----super---%@",[super class]);
//        [self addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
        NSLog(@"self-Class ---------%@",[self class]); // self-Class ---------ViewController
        NSLog(@"isa-Class ---------%@",object_getClass(self)); //   isa-Class ---------NSKVONotifying_Man
        return self;
    }
    return nil;
}
//- (void)setName:(NSString *)name{
//    [self willChangeValueForKey:@"name"];
//    _name = name;
//    [self didChangeValueForKey:@"name"];
//}
//+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key{
//    if ([key isEqualToString:@"name"]) {
//        return NO;
//    }
//    return [super automaticallyNotifiesObserversForKey:key];
//}
//- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
//    NSLog(@"observeValueForKeyPath=-------%@--------change:----%@",keyPath,change);
//}

//+ (BOOL)resolveInstanceMethod:(SEL)sel{ // 查看当前有没有可执行 如果没有，我们可以class_addMethod添加  1号接盘侠
////    if (sel == @selector(foo)) {
////        class_addMethod([self class], sel, (IMP)fooMethod, "v@:");
////        return YES;
////    }
////    return [super resolveInstanceMethod:sel];
//    return YES;
//}
//
//- (id)forwardingTargetForSelector:(SEL)aSelector{ // 使用其他对象 替换  如果没有可替换对象 进入下一步  2号接盘侠
////    if (aSelector == @selector(foo)) {
////        return [[Person alloc] init];
////    }
////    return [super forwardingTargetForSelector:aSelector];
//    return nil;
//}
//
//
//- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{  // 方法签名   3号接盘侠1
//    if ([NSStringFromSelector(aSelector) isEqualToString:@"foo"]) {
//        return [NSMethodSignature signatureWithObjCTypes:"v@:"];
//    }
//    return [super methodSignatureForSelector:aSelector];
//}
//- (void)forwardInvocation:(NSInvocation *)anInvocation{ // 最后一次补救机会， 使用其他对象代替 如果没有可替代的 进入doesNotRecognizeSelector      3号接盘侠2
////    SEL sel = anInvocation.selector;
////    Car *p = [[Car alloc] init];
////    p.defaultColor = [UIColor redColor];
////    NSLog(@"-----car Color ----%@",p.defaultColor);
////    if ([p respondsToSelector:sel]) {
////        [anInvocation invokeWithTarget:p];
////    }else{
////        [self doesNotRecognizeSelector:sel];
////    }
//}

- (void)doesNotRecognizeSelector:(SEL)aSelector{ // 没有可执行的方法
    NSLog(@"doesNotRecognizeSelector-----%@",NSStringFromSelector(aSelector));
}


void fooMethod(id obj , SEL _cmd){ // 动态添加方法   本质是一个添加指向的过程
    NSLog(@"fooMethod------foo");
}


// KVO 在 NSKVONotifying_Man 类中重写的set 方法
//- (void)setName:(NSString *)newName {
//    [self willChangeValueForKey:@"name"];    //KVO 在调用存取方法之前总调用
//    [super setValue:newName forKey:@"name"]; //调用父类的存取方法
//    [self didChangeValueForKey:@"name"];     //KVO 在调用存取方法之后总调用
//}

- (nonnull id)copyWithZone:(nullable NSZone *)zone {
    Man *man = [[self class] allocWithZone:zone];
    man.name = self.name;
    return man;
}
- (nonnull id)mutableCopyWithZone:(nullable NSZone *)zone {
    Man *man = [[self class] allocWithZone:zone];
    man.name = self.name;
    return man;
}
- (instancetype)initWithCoder:(NSCoder *)coder{
//    unsigned int ivasCount ;
//    Ivar *ivas = class_copyIvarList([self class], &ivasCount);
//    for (int i = 0; i < ivasCount ; i ++ ) {
//        Ivar iva = ivas[i];
//        NSString *key = [NSString stringWithUTF8String : ivar_getName(iva)];
//        [self setValue:[coder decodeObjectForKey:key] forKey:key];
//    }
//    return self;
    if (self = [super initWithCoder:coder]) {
        _gender = [coder decodeObjectForKey:@"gender"];
    }
    return self;
}
- (void)encodeWithCoder:(NSCoder *)coder{
//    unsigned int ivasCount ;
//    Ivar *ivas = class_copyIvarList([self class], &ivasCount);
//    for (int i = 0; i < ivasCount ; i ++ ) {
//        Ivar iva = ivas[i];
//        NSString *key = [NSString stringWithUTF8String:ivar_getName(iva)];
//        [coder encodeObject:[self valueForKey:key]];
//    }
    [super encodeWithCoder:coder];
    [coder encodeObject:_gender forKey:@"gender"];
}
-(NSString*)description{
    return [NSString stringWithFormat:@"gender:%@----name:%@",self.gender,self.name];
}
@end
